/*
 * Commissiong_test.c
 *
 *  Created on: 2023年7月31日
 *      Author: fjx
 */
#include "mac/RBFCommon.h"
#include "mac/RBFCommissioning.h"
#include "util.h"
#include "app_log.h"
#include <stdio.h>
#include "mac/MacCrypto.h"
#include "bsp_nvm.h"
#include "device.h"
#include "device_rfmid.h"
#include "Commissiong_test.h"


#define CONFIG_COMMISSIONG_KEY_CRYPTO

join_t  msg={
    .status = EN_COMMISSIONG_JOIN_NODE_PAGING_BUILD_PACKET,
};

uint8_t _key[RBF_KEY_LENGTH_MAX] ={0};
uint8_t _keyA[RBF_KEY_LENGTH_MAX] =KEY_CODEA_DEFAULT;
uint8_t _keyB[RBF_KEY_LENGTH_MAX] =KEY_CODEB_DEFAULT;
uint8_t _keyAB[RBF_KEY_LENGTH_MAX] = {0};

uint8_t _keydefault1[RBF_KEY_LENGTH_MAX] =DEFAULTKEY_1_VALUE_DEFALUT;
uint8_t _keydefault2[RBF_KEY_LENGTH_MAX] =DEFAULTKEY_2_VALUE_DEFALUT;

uint8_t _keysystem[RBF_KEY_LENGTH_MAX]=KEY_SYSTEM_DEFAULT;
uint8_t _keybroadcast[RBF_KEY_LENGTH_MAX]=KEY_BROADCAST_DEFAULT;



void Commissiong_dataInit (void)
{

  msg.status = EN_COMMISSIONG_JOIN_NODE_PAGING_BUILD_PACKET;



}

uint8_t Commissiong_get_device_type(void)
{
  //TODO:APP接口进行替换

  return EN_DEVICE_TYPE_IO_MC;
}

void Commissiong_join_node_paging (join_t  *msg)
{
  SecureElementStatus_t se_ret;
  RBF_RET_STATUS ret;
//  uint8_t packet[255]= {0};
  uint8_t buff[8];


  RBFMacMessageJoinRequest_t join_msg={
      .macAdd2 = 0xabcd,
      .msgSeq = 0x11,
      .msgRetry = 0x22,
      .battV = 0xff,
      .rssi = 0x33,
      .temp = 0x44,
      .qrfR1 = 0x55,
      .qrfR2 = 0x66,
      .echASeq = 0x77,

      .deviceType = 0x88,
      .modelType = 0x99,
      .hardType = 0xaa,
      .macAdd8 = 0,/*0x1a2b3c4d5f6e7f,*/
      .rfVer = 0xabcdef,
      .sVer = 0x56,
      .keyCodeA={0},
      .mac = 0xfe112233,
  };
//  uint8_t codeA_parse[16];
  uint8_t macAdd8[8];
  DS_app_log_info("===test node paging start=== ,status=%d\n",msg->status);
  switch(msg->status){
    case EN_COMMISSIONG_JOIN_NODE_PAGING_BUILD_PACKET:
      /*节点寻呼组包
       *1. RFM随机生成codeA
       *2. 取macAdd8,macAdd2
       *3. 取deviceType
       *4. TODO: (MsgSeq MsgRetry BattV RSSI Temp QrfR1 QrfR2 EchASeq
       *4.      ModelType HardType  RFVer sVe)等值暂未取
       */
      memset(msg->rfm.up,0,DATA_LINK_LENGTH);

      RBF_generate_data_codeA(_key); //随机生成codeA

      memcpy(join_msg.keyCodeA,_key,RBF_KEY_LENGTH_MAX);
      DS_app_log_hexdump_debug("[RFM codeAkey]: ",join_msg.keyCodeA,RBF_KEY_LENGTH_MAX);

      getThisParam(ENpbyMacID,buff); //获取macAdd 8bytes
      join_msg.macAdd8=l_get_be64(buff);
      join_msg.macAdd2= join_msg.macAdd8&0xffff;
      join_msg.deviceType = Commissiong_get_device_type();


      RBF_set_node_paging(join_msg,msg->rfm.up);//packet);
      DS_app_log_hexdump_debug("[node paging] up:",msg->rfm.up,msg->rfm.up[0]+1);
      msg->status = EN_COMMISSIONG_JOIN_NODE_PAGING_NET_AE;
    break;
    case EN_COMMISSIONG_JOIN_NODE_PAGING_NET_AE:
      //数据加解密
#if 1
      RBF_get_data_defaultKey1(_key);
      se_ret = RBF_mac_payload_crypto_dynamic_key(msg->rfm.up,16,_key);
#else
      se_ret = RBF_mac_payload_crypto(msg->rfm.up,16,KEY_ID_DEFAULT_KEY1);//packet
#endif
      DS_app_log_debug("RBF_mac_payload_crypto se_ret = %d\n",se_ret);
      msg->status = EN_COMMISSIONG_JOIN_NODE_PAGING_NET_DATA;
    break;
    case EN_COMMISSIONG_JOIN_NODE_PAGING_NET_DATA:
      //模拟数据发送和接收
#if 1
      memcpy(msg->hub.down,msg->rfm.up,DATA_LINK_LENGTH);
#endif
      msg->status = EN_COMMISSIONG_JOIN_NODE_PAGING_NET_DE;
      break;
    case EN_COMMISSIONG_JOIN_NODE_PAGING_NET_DE:
#if 1
      RBF_get_data_defaultKey1(_key);
      se_ret = RBF_mac_payload_verify_dynamic_key(msg->hub.down,16,_key);
#else
      se_ret = RBF_mac_payload_verify(msg->hub.down,16,KEY_ID_DEFAULT_KEY1);
#endif
      DS_app_log_debug("RBF_mac_payload_verify se_ret = %d\n",se_ret);
      //end of 数据加解密
      msg->status = EN_COMMISSIONG_JOIN_NODE_PAGING_PACKET_PARSE;
    break;
    case EN_COMMISSIONG_JOIN_NODE_PAGING_PACKET_PARSE:
      DS_app_log_hexdump_debug("[Node paging] down:",msg->hub.down,msg->hub.down[0]+1);
      ret = RBF_get_node_paging_packet_parse(msg->hub.down,
                                       RBF_MAC_PACKET_LEN_SIZE+RBF_HEADER_LENGTH_MAX+RBF_MAC_PAYLOAD_JOIN_REQ_LEN,
                                       &join_msg);


      if(ret == 0 ){
          /*HUB取deviceType,mac,codeA-->计算RfmID
           *
           */
          l_put_be64(join_msg.macAdd8,macAdd8);
          memcpy(msg->join_info.codeA,join_msg.keyCodeA,RBF_KEY_LENGTH_MAX);
          memcpy(msg->join_info.mac,macAdd8,8);
          msg->join_info.deviceType = join_msg.deviceType;
          //
          DS_app_log_info("*** deviceType = %d\n",msg->join_info.deviceType);
          DS_app_log_hexdump_debug("node mac:",msg->join_info.mac,8);

          //写入nvm
          if( setRfmId(msg->join_info.deviceType,msg->join_info.mac,&msg->join_info.rfmid) == 0){
              //codeAB
              RBF_get_data_codeB(_key);
              XorDataLine(_key,msg->join_info.codeA,RBF_KEY_LENGTH_MAX);
              setNodeJoinCodeAB(_key,msg->join_info.rfmid);
              DS_app_log_info("***rfmid = %d \n",msg->join_info.rfmid);
              DS_app_log_hexdump_debug("Hub get codeAB:",_key,RBF_KEY_LENGTH_MAX);

              //
//              getNodeJoinCodeAB(_key,msg->join_info.rfmid);
//              DS_app_log_hexdump_debug("Hub get codeAB:",_key,RBF_KEY_LENGTH_MAX);

          }
          DS_app_log_hexdump_debug("parse codeAkey: ",join_msg.keyCodeA,RBF_KEY_LENGTH_MAX);
      }
      msg->status = EN_COMMISSIONG_GW_ALLOW_JOIN_NET_BUILD_PACKET;
    break;
    default:
      break;
  }
}

void Commissiong_gw_allow_join_net  (join_t  *msg)
{
  SecureElementStatus_t se_ret;
  RBF_RET_STATUS ret;
  //uint8_t packet[255]= {0};
  size_t len;
  RBFMacHeader_t hdr;
  RBFMacMessageGWAlloawJoinNetwork_t gw_join_msg ={
      .macAdd4 = 0x11223344,
      .rollingCode = 0x55667788,
      .systemID = 0xaabbcc,  //3Bytes
      .localID = 0xddee,
      .broadcastKeyCode = {0},
      .keyCodeB = {0},
      .systemKeyCode = {0},//
      .mac = 0xa55ab66b,
  };
  switch(msg->status){
      case EN_COMMISSIONG_GW_ALLOW_JOIN_NET_BUILD_PACKET:
        /*1.取macAdd4,codeB,LocalID，broadcastKeyCode,systemKeyCode
         *2.TODO:(RollingCode SystemID)未取
         * 从NVM获取CodeB,broadcastKeyCode,systemKeyCode
         */

        RBF_get_data_codeB(_key);  //获取keyCodeB
        memcpy(gw_join_msg.keyCodeB,_key,RBF_KEY_LENGTH_MAX);
        RBF_get_data_systemKeyCode(_key);//获取
        memcpy(gw_join_msg.systemKeyCode,_key,RBF_KEY_LENGTH_MAX);
        RBF_get_data_broadcastKeyCode(_key);
        memcpy(gw_join_msg.broadcastKeyCode,_key,RBF_KEY_LENGTH_MAX);

        gw_join_msg.macAdd4 = l_get_be64(msg->join_info.mac)&0xFFFFFFFF;
        /* 1. HUB 先保存ABke
         * 2. systemKeyCode进行AES(codeAB)加密
         */
        //1.保存CodeAB
#if 0
        RBF_get_data_codeA(_key);
#else //从协议中获取
        memcpy(_key,msg->join_info.codeA,RBF_KEY_LENGTH_MAX);
#endif
        XorDataLine(_key,gw_join_msg.keyCodeB,RBF_KEY_LENGTH_MAX);
        RBF_set_data_codeAB(_key);  //保存
        memcpy(msg->join_info.codeAB,_key,RBF_KEY_LENGTH_MAX);
        //set codeAB key_id
        RBF_get_data_codeAB(_key);
        RBF_set_keyid_codeAB(_key);
        RBF_key_group_info_log();
        //2.systemKeyCode(AES)
#if defined (CONFIG_COMMISSIONG_KEY_CRYPTO)
        RBF_aes_ae(KEY_ID_CODEAB,gw_join_msg.systemKeyCode,RBF_KEY_LENGTH_MAX,_key,RBF_KEY_LENGTH_MAX,&len);
        memcpy(gw_join_msg.systemKeyCode,_key,RBF_KEY_LENGTH_MAX);
//        DS_app_log_hexdump_debug("**broadcast[C]**",gw_join_msg.broadcastKeyCode,RBF_KEY_LENGTH_MAX);
        RBF_aes_ae(KEY_ID_CODEAB,gw_join_msg.broadcastKeyCode,RBF_KEY_LENGTH_MAX,_key,RBF_KEY_LENGTH_MAX,&len);
        memcpy(gw_join_msg.broadcastKeyCode,_key,RBF_KEY_LENGTH_MAX);
//        DS_app_log_hexdump_debug("**broadcast[C]**",gw_join_msg.broadcastKeyCode,RBF_KEY_LENGTH_MAX);
#endif
        gw_join_msg.localID = msg->join_info.rfmid;// TODO:localID = rfmID
        hdr.destID =  gw_join_msg.localID;
        DS_app_log_info("===test gw allow join start===\n");
        RBF_set_gw_allow_join_net(hdr,gw_join_msg,msg->hub.up);
        DS_app_log_hexdump_debug("[GW Allow Join] up:",msg->hub.up,msg->hub.up[0]+1);
        msg->status = EN_COMMISSIONG_GW_ALLOW_JOIN_NET_NET_AE;
      break;
      case EN_COMMISSIONG_GW_ALLOW_JOIN_NET_NET_AE:
        //payload数据加解密
#if 1
        RBF_get_data_defaultKey1(_key);
        se_ret = RBF_mac_payload_crypto_dynamic_key(msg->hub.up,16,_key);
#else
        se_ret = RBF_mac_payload_crypto(msg->hub.up,16,KEY_ID_DEFAULT_KEY1);
#endif
        DS_app_log_debug("RBF_mac_payload_crypto se_ret = %d\n",se_ret);
        msg->status = EN_COMMISSIONG_GW_ALLOW_JOIN_NET_NET_DATA;
        break;
      case EN_COMMISSIONG_GW_ALLOW_JOIN_NET_NET_DATA:
#if 1
        memcpy(msg->rfm.down,msg->hub.up,DATA_LINK_LENGTH);
#endif
        msg->status = EN_COMMISSIONG_GW_ALLOW_JOIN_NET_NET_DE;
        break;
      case EN_COMMISSIONG_GW_ALLOW_JOIN_NET_NET_DE:
#if 1
        RBF_get_data_defaultKey1(_key);
        se_ret = RBF_mac_payload_verify_dynamic_key(msg->rfm.down,16,_key);
#else
        se_ret = RBF_mac_payload_verify(msg->rfm.down,16,KEY_ID_DEFAULT_KEY1);
#endif
        DS_app_log_debug("RBF_mac_payload_verify se_ret = %d\n",se_ret);
        //end of 数据加解密
        msg->status = EN_COMMISSIONG_GW_ALLOW_JOIN_NET_PACKET_PARSE;
        break;
      case EN_COMMISSIONG_GW_ALLOW_JOIN_NET_PACKET_PARSE:
        ret = RBF_get_gw_allow_join_net(msg->rfm.down,RBF_MAC_PACKET_LEN_SIZE+RBF_HEADER_LENGTH_MAX+RBF_MAC_PAYLOAD_GW_ALLOW_JOIN_NETWORK_LEN);

        if(ret == 0 ){
            /*获取codeB,计算codeAB,并解密systemKey,broadcastKey
             *
             */
            RBFMacMessageGWAlloawJoinNetwork_t msg_pyd;
            RBFMacHeader_t hdr;
            RBF_header_parse(msg->rfm.down,RBF_MAC_PACKET_LEN_SIZE+RBF_HEADER_LENGTH_MAX, &hdr);
            msg->join_info.rfmid = hdr.destID;
            DS_app_log_info("***RFMId = %d \n",msg->join_info.rfmid);

            RBF_gw_allow_join_net_payload_packetToMsg(msg->rfm.down,&msg_pyd);
//            DS_app_log_hexdump_debug("**broadcast[C]**",msg_pyd.broadcastKeyCode,RBF_KEY_LENGTH_MAX);

            {
            //1.RFM保存CodeAB
            RBF_get_data_codeA(_key);
            XorDataLine(_key,msg_pyd.keyCodeB,RBF_KEY_LENGTH_MAX);
            RBF_set_data_codeAB(_key);  //保存
            DS_app_log_hexdump_debug("RFM CodeAB:",_key,RBF_KEY_LENGTH_MAX);

            }

            //2.aes 解密
#if defined (CONFIG_COMMISSIONG_KEY_CRYPTO)
            //systemKeyCode
            DS_app_log_hexdump_debug("***system code(cipher)",msg_pyd.systemKeyCode,RBF_KEY_LENGTH_MAX);
            RBF_aes_de(KEY_ID_CODEAB,msg_pyd.systemKeyCode,RBF_KEY_LENGTH_MAX,_key,RBF_KEY_LENGTH_MAX,&len);
            memcpy(msg_pyd.systemKeyCode,_key,RBF_KEY_LENGTH_MAX); //copy
            DS_app_log_hexdump_debug("***system code(plain)",msg_pyd.systemKeyCode,RBF_KEY_LENGTH_MAX);




            //broadcastkey
            DS_app_log_hexdump_debug("***broadcast code(cipher)",msg_pyd.broadcastKeyCode,RBF_KEY_LENGTH_MAX);
            RBF_aes_de(KEY_ID_CODEAB,msg_pyd.broadcastKeyCode,RBF_KEY_LENGTH_MAX,_key,RBF_KEY_LENGTH_MAX,&len);
            memcpy(msg_pyd.broadcastKeyCode,_key,RBF_KEY_LENGTH_MAX);
            DS_app_log_hexdump_debug("***broadcast code(plain)",msg_pyd.broadcastKeyCode,RBF_KEY_LENGTH_MAX);


#endif
#if 1       //RFM 测试数据(该数据保存在HUB)
            RBF_get_data_codeB(_key);
            DS_app_log_info("codeBkey %s \n\n\n",(memcmp(_key,msg_pyd.keyCodeB,RBF_KEY_LENGTH_MAX) == 0 ?"same":"diff"));
            RBF_get_data_broadcastKeyCode(_key);
            DS_app_log_info("broadcastKeyCode %s \n\n\n",(memcmp(_key,msg_pyd.broadcastKeyCode,RBF_KEY_LENGTH_MAX) == 0 ?"same":"diff"));
            DS_app_log_hexdump_debug("broadcastKey:",_key,RBF_KEY_LENGTH_MAX);
            RBF_get_data_systemKeyCode(_key);
            DS_app_log_info("systemKey %s \n\n\n",(memcmp(_key,msg_pyd.systemKeyCode,RBF_KEY_LENGTH_MAX) == 0 ?"same":"diff"));
#endif
            //保存RFM
            RBF_set_data_broadcastKeyCode(msg_pyd.broadcastKeyCode);
            RBF_set_data_systemKeyCode(msg_pyd.systemKeyCode);



        }
        DS_app_log_hexdump_debug("[GW Allow Join] down:",msg->rfm.down,msg->rfm.down[0]+PACKET_0_OUT_OFFSET);

        msg->status = EN_COMMISSIONG_JOIN_CONFIRM_BUILD_PACKECT;
        break;
      default:
        break;
  }
}





void Commissiong_KeyInit (void)
{
  uint8_t buf[NODE_JOIN_INFO_LENGTH];

  //1.赋值key到NVM
  RBF_set_data_codeA(_keyA);
  //自动生成 RBF_set_data_codeB(_keyB);
  RBF_set_data_defaultKey1(_keydefault1);
  RBF_set_data_defaultKey2(_keydefault2);

  //HUB端
  RBF_set_data_systemKeyCode(_keysystem);
  RBF_set_data_broadcastKeyCode(_keybroadcast);


  //2.从NVM取key,并得到key_id
  RBF_get_data_defaultKey1(_key);
  RBF_set_keyid_defaultKey1(_key);
//  RBF_get_data_defaultKey2(_key);
//  RBF_set_keyid_defaultKey2(_key);

  //RBM
  RBF_get_data_codeA(_key);
  RBF_set_keyid_codeA(_key);



  RBF_key_group_info_log();

  //HUB INFO

  if(getThisParam(ENbyNodeJoinInfo,buf) != 0){
      DS_app_log_info("HUB join data init ...\n");
      clearNodeJoinCount();
      DS_app_log_info("join count=%d",getNodeJoinCount());
      RBF_generate_data_codeB(_key);
  }

}
void Commissiong_join_confirm (join_t  *msg)
{
  SecureElementStatus_t se_ret;
//  RBF_RET_STATUS ret;
//  uint8_t packet[255]= {0};
  uint8_t buff[8];

  RBFMacMessageNodeJoinConfirm_t join_confirm_msg = {
      .macAdd2 = 0xabcd,
      .msgSeq = 0x11,
      .msgRetry = 0x22,
      .battV = 0xff,
      .rssi = 0x33,
      .temp = 0x44,
      .qrfR1 = 0x55,
      .qrfR2 = 0x66,
      .echASeq = 0x77,

      .deviceType = 0x88,
      .modelType = 0x99,
      .hardType = 0xaa,

      .rfVer = 0xabcdef,
      .sVer = 0x56,
      .mac = 0xfe112233,
  };
  DS_app_log_info("===test join confirm start===,status =%d\n",msg->status);
  switch(msg->status){
    case EN_COMMISSIONG_JOIN_CONFIRM_BUILD_PACKECT:
      /*1. 取MacAdd2,macAdd8,DeviceType
       *2. DOTO: (MsgSeq MsgRetry BattV RSSI Temp QrfR1 QrfR2 EchASeq
       *  ModelType HardType  RFVer sVer)未取
       *
       *
       */
      getThisParam(ENpbyMacID,buff); //获取macAdd 8bytes
      join_confirm_msg.macAdd8=l_get_be64(buff);
      join_confirm_msg.macAdd2= join_confirm_msg.macAdd8&0xffff;
      join_confirm_msg.deviceType = Commissiong_get_device_type();

      RBF_set_node_join_confirm(join_confirm_msg,msg->rfm.up);
      DS_app_log_hexdump_debug("[Join Confirm] up:",msg->rfm.up,msg->rfm.up[0]+1);
      msg->status = EN_COMMISSIONG_JOIN_CONFIRM_NET_AE;
      break;
    case EN_COMMISSIONG_JOIN_CONFIRM_NET_AE:
      //数据加解密
#if 1
      RBF_get_data_codeAB(_key);
      se_ret = RBF_mac_payload_crypto_dynamic_key(msg->rfm.up,12,_key);
#else
      se_ret = RBF_mac_payload_crypto(msg->rfm.up,12,KEY_ID_CODEAB);
#endif
      DS_app_log_debug("RBF_mac_payload_crypto ret = %d\n",se_ret);
      msg->status = EN_COMMISSIONG_JOIN_CONFIRM_NET_DATA;
      break;
    case EN_COMMISSIONG_JOIN_CONFIRM_NET_DATA:
#if 1
      memcpy(msg->hub.down,msg->rfm.up,DATA_LINK_LENGTH);
#endif
      msg->status = EN_COMMISSIONG_JOIN_CONFIRM_NET_DE;
      break;
    case EN_COMMISSIONG_JOIN_CONFIRM_NET_DE:
#if 1
      getNodeJoinCodeAB(_key,msg->join_info.rfmid);
     // _key[1] += 0x02;
      se_ret = RBF_mac_payload_verify_dynamic_key(msg->hub.down,12,_key);
#else
      se_ret = RBF_mac_payload_verify(msg->hub.down,12,KEY_ID_CODEAB);
#endif
      DS_app_log_debug("RBF_mac_payload_verify ret = %d\n",se_ret);
      if(se_ret != 0){
          DS_app_log_error("!Join confirm aes-ccm error!\n");
      }
      //end of 数据加解密
      msg->status = EN_COMMISSIONG_JOIN_CONFIRM_PACKECT_PARSE;
      break;
    case EN_COMMISSIONG_JOIN_CONFIRM_PACKECT_PARSE:
      DS_app_log_hexdump_debug("[Join Confirm] down:",msg->rfm.down,msg->rfm.down[0]+1);
      if( RBF_get_node_join_confirm(msg->hub.down,RBF_MAC_PACKET_LEN_SIZE+RBF_HEADER_LENGTH_MAX+RBF_MAC_PAYLOAD_JOIN_CONFIRM_LEN)== 0 ){

          RBFMacMessageNodeJoinConfirm_t pack_msg;
          RBF_node_join_confirm_payload_packetToMsg(msg->hub.down,&pack_msg);
          if(pack_msg.macAdd2 != (l_get_be64(msg->join_info.mac)&0xFFFF)){
              DS_app_log_error("*** mac address is diff [join confirm]\n");
          }

          msg->status = EN_COMMISSIONG_JOIN_CONFIRM_SUCCESS;//HUB收到注册成功，
      }
      DS_app_log_info("===test join confirm end===\n");


      break;
    default:
      break;
  }






}


void Commissiong_Init (void)
{

  DS_nvmInit();
  Commissiong_dataInit();
  Commissiong_KeyInit();
  while(1){
    Commissiong_join_node_paging(&msg);
    Commissiong_gw_allow_join_net(&msg);
    Commissiong_join_confirm(&msg);

    if(msg.status == EN_COMMISSIONG_JOIN_CONFIRM_SUCCESS)
    {
        msg.status = EN_COMMISSIONG_IDLE;

    }

    if(msg.status == EN_COMMISSIONG_IDLE) return;



  }

}
